<?php

namespace app\command;

use app\helper\Schema;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class SchemaMigrateCommand extends Command {

    use \app\helper\SqlTraits;

    public function configure() {
        $this->setName('schema:migrate')->setDescription('执行SQL文件')
                ->addArgument('file', InputArgument::OPTIONAL, '需要执行的sql文件路径(支持相对路径和绝对路径)', DIFFSQL)
                ->addArgument('dbname', InputArgument::OPTIONAL, '需要导入的数据库,支持逗号分割', DBNAME);
    }

    public function execute(InputInterface $input, OutputInterface $output) {
        $file = $input->getArgument('file');
        if (!($filepath = static::searchFile($file))) {
            $output->writeln('<error>SQL文件不存在或者不可读</error>');
            exit;
        }
        $dbname = $input->getArgument('dbname');
        // sql 文件的解析，剔除 use 语法
        $sql_content = static::parseFile($filepath);
        $output->writeln(sprintf('<info>%s</info>', $sql_content));
        $helper = $this->getHelper('question');
        $question = new ConfirmationQuestion("确定将以上SQL应用到 $dbname 数据库?[Y/N(default)]", FALSE);
        if (!$helper->ask($input, $output, $question)) {
            return;
        }
        $db_error = [];
        $dbnames = explode(',', $dbname);
        foreach ($dbnames as $dbname) {
            try {
                Schema::getDefaultConnection()->beginTransaction();
                Schema::getDefaultConnection()->exec(sprintf('USE `%s`;', $dbname));
                Schema::getDefaultConnection()->exec($sql_content);
                Schema::getDefaultConnection()->commit();
            } catch (\PDOException $exc) {
                $db_error[$dbname] = $exc->getMessage();
                Schema::getDefaultConnection()->rollBack();
            }
        }
        $output->writeln('<info>导入数据库完成</info>');
        if (!empty($db_error)) {
            $output->writeln('<info>以下是导入失败的数据库、及错误说明：</info>');
        }
        foreach ($db_error as $db => $error) {
            $output->writeln(sprintf('<error>%s::::%s</error>', $db, $error));
        }
    }

}
